package com.test01.java8;

import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import junit.framework.TestCase;

/**
 * <p>Title: TestMethodRef</p>  
 * <p>Description: 方法  / 构造器引用  
 * @author felixli(李宝平)
 * @date 2019年7月28日 
 */
public class TestMethodRef extends TestCase {

	/**
	 * 
	 * 	知识点一：
	 * 	方法引用:若Lambda 体中的内容有方法实现了，我们可以使用“方法引用”
	 * (可以理解为方法引用是Lambda表达式的另一种表现形式)
	 * 
	 * 
	 * 	主要语法有三种：
	 * 
	 * 	对象::实例方法
	 * 
	 * 	类::静态方法名
	 * 
	 * 	类::实例方法名
	 * 
	 *
	 * 	注意：
	 * 	1、在使用方法引用时,Lambda 体调用的方法的参数与返回类型，必须和函数式接口中的方法的参数和返回类型保持一致
	 * 	2、若Lambda 参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用  ClassName :: method
	 * 
	 * 
	 * 
	 * 
	 * 	知识点二：
	 * 	构造器引用：
	 * 	格式：ClassName :: new
	 * 	
	 * 	注意：需要调用的构造器的参数列表需要和函数式接口中抽象方法的参数列表保存一致
	 * 
	 * 
	 * 	知识点三：
	 * 	数组引用：
	 * 	格式：type[] :: new
	 */
	
	//对象::实例方法
	public void test1() {
		//Lambda表达式形式1
		Consumer<String> con1 = (x) -> System.out.println(x);
		con1.accept("aaaaaaaaa");
		
		//方法引用
		Consumer<String> con2 = System.out::println;
		con2.accept("bbbbbbbbb");
		
		
		Employee emp = new Employee("张三", 26, "男");
		
		Supplier<String> suplier1 =  () -> emp.getName();
		String name = suplier1.get();
		
		Supplier<Integer> suplier2 =  emp::getAge;
		int age = suplier2.get();
		
		System.out.println("此员工的姓名叫: " + name + ",今年" + age + "了。");
	}
	
	//类::静态方法名
	public void test2() {
		//Lambda表达式形式
		Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
		System.out.println(com1.compare(10, 20));
		//方法引用方式
		Comparator<Integer> com2 = Integer::compare;
		System.out.println(com2.compare(100, 60));
	}
	
	//类::实例方法名
	public void test3() {
		BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
		System.out.println(bp1.test("aaa", "bbb"));
		
		BiPredicate<String, String> bp2 = String::equals;
		System.out.println(bp2.test("aaa", "aaa"));
	}
	
	//构造器引用(无参)
	public void test4() {
		//Lambda表达式形式1
		Supplier<Employee> sup1 = () -> new Employee();
		Employee emp1 = sup1.get();
		emp1.setName("张三");
		//构造器引用
		Supplier<Employee> sup2 = Employee::new;
		sup2.get().setName("李四");
	}
	
	//构造器引用(有参)
	public void test5() {
		//Lambda表达式形式1
		Function<Integer, Employee> func1 = (x) -> new Employee(x);
		Employee emp1 = func1.apply(26);
		System.out.println("今年" + emp1.getAge() + "了。");
		
		//构造器引用
		Function<Integer, Employee> func2 = Employee :: new;
		Employee emp2 = func2.apply(30);
		System.out.println("今年" + emp2.getAge() + "了。");
		
		
	}
	
	// 数组引用
	public void test6() {
		//Lambda表达式形式
		Function<Integer, String[]> func1 = (x) -> new String[x];
		String[] array1 = func1.apply(15);
		System.out.println(array1.length);
		
		// 数组引用
		Function<Integer, String[]> func2 = String[]::new;
		String[] array2 = func2.apply(30);
		System.out.println(array2.length);
	}
}
